//
// Created by ZYZ on 2020/6/18.
//

#include <stdio.h>
#include <stdlib.h>
#include "../../include/define.h"
#include "../../include/type_linear_queue.h"
#include "linear_queue.h"

//ー-ーーー循环队列的基本操作的算法描述

//构造一个空队列 Q
Status InitQueue(SqQueue &Q) {
    Q.base = (QElemType *) malloc(MAXQSIZE * sizeof(QElemType));
    if (!Q.base) exit(OVERFLOW);                //存储分配失败
    Q.front = Q.rear = 0;
    return OK;
}

//销毁队列 Q, Q 不再存在
Status DestroyQueue(SqQueue &Q){
    if(Q.base)
        free(Q.base);
    else
        return ERROR;
    Q.base = NULL;
    Q.front = Q.rear = 0;
    return OK;
}

// 清空顺序存储队列                                //数据不需要抹除，只需改变下标位置
Status ClearQueue(SqQueue &q) {
    q.front = 0;
    q.rear = 0;
    return OK;
}

//若队列 Q 为空队列，则返回 TRUE，否则返回 FALSE
Status QueueEmpty(SqQueue Q){
    if(Q.front == Q.rear)
        return OK;
     else
         return ERROR;
}

//返回 Q 的元素个数，即队列的长度
int QueueLength(SqQueue Q) {
    return (Q.rear - Q.front + MAXQSIZE) % MAXQSIZE;
}

//若队列不空，则用 e 返回 Q 的队头元素，并返回 OK；否则返回 ERROR
Status GetHead(SqQueue Q, QElemType &e){
    if(QueueEmpty(Q))
         return ERROR;
     e = Q.base[Q.front];
     return OK;
}

//插入元素 e 为 Q 的新的队尾元素
Status EnQueue(SqQueue &Q, QElemType e) {

    if ((Q.rear + 1) % MAXQSIZE == Q.front)
        return ERROR;                            //队列满

    Q.base[Q.rear] = e;
    Q.rear = (Q.rear + 1) % MAXQSIZE;

    return OK;
}

//若队列不空，则删除 Q 的队头元素，用 e 返回其值，并返回 OK; 否则返回 ERROR
Status Dequeue(SqQueue &Q, QElemType &e) {

    if (Q.front == Q.rear)
        return ERROR;

    e = Q.base[Q.front];
    Q.front = (Q.front + 1) % MAXQSIZE;

    return OK;
}

/// 遍历打印队列的数据元素
Status QueueTraverse(SqQueue Q, Status  (* visit) (QElemType e)){
    int i = Q.front;
    while (i != Q.rear) {
        visit(Q.base[i]);
        i = (i + 1) % MAXQSIZE;
    }
    printf("\n");
    return OK;
}
